package scalaLearning.scalaBasic

object TestFunc {

  def sayMyName(name : String = "Jack"){  //没有等号"=",表示不要返回值
    println(name)
  }


  def sumMoreParameters(elem : Int*) = {   //表示有多个 Int 类型的参数
    var sum = 0
    for(e <- elem){
     // println(e)
      sum += e
    }
    sum
  }
  println(sumMoreParameters(1,2,3,4,5,6))






  def add(a:Int,b:Int) = a+b


  def add2  = add(_:Int,2)  //根据已有的函数定义新的函数
// 第一个参数是Int类型的， 第二个参数是固定的为2


  // 定义递归函数体
  //	f(n)=f(n)*f(n-1)   //传入参数n为整型参数
  def fac(n:Int):Int = if( n <= 0) 1 else n*fac(n-1)
//                            递归终止条件



  //	函数柯里化
  // 柯里化,柯里化比较有意思,就是说定义
  // 把这个参数一个个独立开来写,这就是柯里化,它可以达到什么效果呢？
  //柯里化就是把参数可以分开来，把部分函数参数可以用下划线来代替
  def mulitply(x:Int)(y:Int) = x*y

  def m2 = mulitply(2)_;//println( m2(123));
  // 同学们可能会说，这个看起来没有什么用处啊，但是我们说柯里化在   递归，和控制抽象  方面比较有用
  //	在目前我们不去深究这个使用场景，现在就是让大家知道有这么个形式，大家掌握到这就可以了
  //	柯里化就是把参数可以分开来，把部分函数参数可以用下划线来代替



  //	=> 匿名函数函数句柄声明方式
  val t = ()=>333//声明了一个函数对象付给了t    这个函数的参数是空()没有参数   匿名函数赋给了t  以后想用这个匿名函数直接调用 t()方法就可以了
//val t = ()=>{333} //{}中是方法体   【原型】 333是方法体 {333}中的最后一个参数，那么它就会被返回出去
//定义匿名函数的方法  匿名函数的函数句柄 = 函数参数列表（）=>后边是方法体{}，大括号中的方法体可以定义很多内容，注意分辨



  //    ":"后面是数据类型,c代表传进来的参数   c这个位置需要传一个匿名函数进来，
  // 这个匿名函数需要符合的类型结构是 ()=>Int  首先前面是一个无参数的，其次后面的返回值是int类型。
  // 你只有传递这种方式的匿名函数给testfunc02  它才能运行
  def testfunc02(c : ()=>Int ){//你传递过来的匿名函数首先复制给参数c，然后直接调用c就可以了
    println(c())  //在方法体里面才真正调用函数执行
    1000
  }
  //	println(testfunc02(t))     t是一个匿名函数  它参数为空（） 返回值是333正好是int类型  val t = ()=>333
//  输出结果会是
// 333
// ()        此处函数么有“=”即没有返回值  println(testfunc02(t))  打印出的为"()"

 // def testfunc02(c : ()=>Int )={//你传递过来的匿名函数首先复制给参数c，然后直接调用c就可以了
//    println(c())  //在方法体里面才真正调用函数执行
 //   1000
//  }
  //	println(testfunc02(t))     t是一个匿名函数  它参数为空（） 返回值是333正好是int类型  val t = ()=>333
  //  输出结果会是
  // 333
  // 1000  因为 “=”会自动推断返回值的类型
/*
* def testfunc02(c : ()=>Int ){//没有等号"=",表示不要返回值，
* 其非省略模式为  def testfunc02(c : ()=>Int )：Unit={}
* 省略之后为  def testfunc02(c : ()=>Int ){}省略之后会对其类型进行自动的推断
    println(c())//在方法体里面才真正调用函数执行
    1000
  }
* */



  //	匿名函数 函数句柄d1
  val d1 = (a:Int)=> a+100;//声明一个匿名函数：有一个参数a，返回a+100，然后赋值给d1这个常量

  //	匿名函数作为参数,其实就是参数名,后面跟上参数类型,然后是表达式
  //  函数名  参数       参数类型(匿名函数)  函数体
  def testf1(callback : (Int,Int)=>Int )={     //函数 testf1()的参数，命名为callback，参数是一个匿名函数(Int,Int)=>Int
    println(callback(123,123))                 // 匿名函数的两个参数是Int类型，返回值也是Int类型
  }
  //在这个里面才去调用callback ，数据并不是传进来的
  // 而是在testf1()里面写死的。testf1()函数里面是拿到了真正的数据
  // 真正的对数据进行怎样的操作是交给匿名函数(Int,Int)=>Int去做，这就是函数式编程的一大优点
  // 即，你在testf1里面有权限获取到数据，但是你并不知道对这个数据进行怎样的操作，　你可以定义一个匿名函数作为参数
  // 　操作逻辑交给别人　,你有权限拿到数据，但是匿名函数没有权限拿到这个数据，但是他知道怎么去操作　　　　　　　　　


  //    嵌套函数,其实就是def里面套一个def
  def add3(x:Int, y:Int ,z:Int) : Int = {
    def add2(x:Int, y:Int):Int = {
      x + y
    }
    add2(add2(x,y),z)//把前两个进行相加，然后把第三个进行相加
  }







  //==============================================================================================================
  //  能否看懂？？？
  // ":"后边是参数类型，那么f是函数sum()的一个参数，sum()的参数是一个匿名函数， 匿名函数的类型是    Int类型到Int类型的一个变换；
  // ":"后边是函数的返回类型，返回一个匿名函数类型，
  // 这个匿名函数是 具有两个Int参数，返回一个Int参数的匿名函数类型
  //sum()函数，你给他传递一个匿名函数，他会给你返回一个匿名函数
  //方法体里面的返回回去的是最后一行 sumF
  //  sumF是上边定义的def sumF()函数
  //sum()函数如何调用呢？？传递一个匿名函数进去
  // def sum(f : (Int) => Int) : (Int , Int) => Int = {
  //          只有一个参数()省略
  def sum(f : Int => Int) : (Int , Int) => Int = {
    def sumF(a : Int , b : Int) : Int =          // sumF()这个函数，与匿名函数要求的格式(Int , Int) => Int保持一致
      if (a >b ) 0 else f(a) + sumF( a + 1 , b)
    sumF
  }
  //传递一个匿名函数  匿名函数类型是 Int到Int的
  //sum()调用完之后会返回一个函数   返回的复制给sumInts这个名称
  //    def sumInts = sum( x => x)//x是一个匿名函数x到x的变换
  // println(sumInts(1,2))






  //	  def sum(f : Int => Int) : (Int , Int) => Int = {
  //			  def sumF(a : Int , b : Int) : Int ={
  //					  if (a >b ) 0 else f(a) + sumF( a + 1 , b)
  //			  }
  //			  return sumF
  //	  }


  def main(args: Array[String]) {
//        sayMyName("rose")
//        sayMyName()
//        println(sumMoreParameters(1,2,3,4,5,6))
//
//       println(add(2,3))
//       println(add2(7));
//
//    		println(fac(5));
//    		println(d1(4))
//
//        	println(t())
//
//    		 println( mulitply(123)(123));
//       		 println( m2(123));
//
//
//    	 	println(testfunc02(t))
//
//    		testf1((a:Int,b:Int)=>{println(a*b);a*b})  //callback : (Int,Int)=>Int
//    //匿名函数callback : (Int,Int)=>Int  类型前面要两个参数 Int类型；  匿名函数的方法体在{}中，即打印a*b ，
//    // 并把a*b的值返回回去也是Int类型，符合匿名函数的规定
//
//
//
//    testf1(add);
//
//    println(add3(1,2,3))
//
//    def sum(f :Int => Int) : (Int , Int) => Int = {
//      def sumF(a : Int , b : Int) : Int ={
//        if (a >b ) 0 else f(a) + sumF( a + 1 , b)
//      }
//      return sumF
//    }
//
//
//
//    //传递一个匿名函数  匿名函数类型是 Int到Int的
//    //sum()调用完之后会返回一个函数   返回的复制给sumInts这个名称
//    def sumInts = sum( x => x)
//    println(sumInts(1,2))
//    val tttt = (a:Int,b:Int)=>a*b;
//    testf1(tttt);
//    testf1((a:Int,b:Int)=>a*b)


    val a = "@@21234"
    val b = a.substring(3)
    println(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>")
    println(b)
  }



}